home *** CD-ROM | disk | FTP | other *** search
- /* jjn.c
- * AUTHOR: Cy Booker, cy@cheepnis.demon.co.uk
- * LICENSE: FreeWare, Copyright (c) 1995 Cy Booker
- *
- * filter: * 7 5
- * 3 5 7 5 3
- * 1 3 5 3 1 (1/48)
- */
-
- #include "internal.h"
-
- #include <assert.h>
- #include <string.h> /* memset() */
- #include <stdlib.h> /* calloc() */
-
- #include "OS:hourglass.h"
- #include "OS:macros.h"
-
-
-
- /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- */
-
- extern bool process_gif_8bpp_jarvis_judice_ninke(
- const process_gif *p) {
- byte *rove;
- int width, height;
- int x, y;
- const os_colour *palette;
- int line_length;
- int *buffer, *this_row, *next_row, *botm_row;
- int buffer_width;
- int red, grn, blu;
- os_colour colour;
- int error_red, error_grn, error_blu;
- int temp_red, temp_grn, temp_blu;
- rgbtupleout error;
- rgbtupleout_fn fn;
-
- assert(p);
- assert(p->pixel_width > 0);
- assert(p->pixel_height > 0);
- assert(p->in_palette.colours);
- assert(p->fn);
-
- /*
- * jarvis_judice_ninke requires storing error info for two pixels to right and two pixels to left
- * so we will just allocate two extra columns for each row and not do any edge checks
- * each entry is stored as {r*SCALE, g*SCALE, b*SCALE}
- */
- buffer_width = (2 + p->pixel_width + 2) * 3;
- buffer = calloc(1, sizeof(*buffer) * (buffer_width * 3));
- if (!buffer) {
- /*
- * oh dear
- */
- return TRUE;
- }
-
- error.palette = p->out_palette; /* structure copy */
- /*
- * not we pre-load values from the process_gif array
- * because it considerably helps the compiler produce better code
- */
- rove = p->buffer;
- width = p->pixel_width;
- height = p->pixel_height;
- palette = p->in_palette.colours;
- line_length = p->line_length;
- fn = p->fn;
- for (y= height; (y > 0); y--) {
- if ((y & 7) == 0) {
- xhourglass_percentage((y * 100) / height);
- }
- this_row = buffer + (buffer_width * ((y + 3) % 3)) + 2*3;
- next_row = buffer + (buffer_width * ((y + 2) % 3)) + 2*3;
- botm_row = buffer + (buffer_width * ((y + 1) % 3)) + 2*3;
- /* bottom row has no errors */
- memset(botm_row, 0, sizeof(*botm_row) * (buffer_width - 2*3));
- /*
- * note that just because we are actually scanning/outputting right to left
- * doesn't matter as far as jarvis_judice_ninke is concerned
- * although it might help if we could ``snake''
- */
- for (x= width - 1; (x >= 0); x--) {
- INPUT;
-
- red += *this_row++; /* add in errors from all rows */
- grn += *this_row++;
- blu += *this_row++;
-
- PROCESS;
-
- temp_red = (red * 7) / 48; error_red = red - (2 * temp_red);
- temp_grn = (grn * 7) / 48; error_grn = grn - (2 * temp_grn);
- temp_blu = (blu * 7) / 48; error_blu = blu - (2 * temp_blu);
- this_row[ 0] += temp_red; /* this[ 1] += 7/48 */
- this_row[ 1] += temp_grn;
- this_row[ 2] += temp_blu;
-
- next_row[ 0] += temp_red; /* next[ 0] += 7/48 */
- next_row[ 1] += temp_grn;
- next_row[ 2] += temp_blu;
-
- temp_red = (red * 5) / 48; error_red -= 4 * temp_red;
- temp_grn = (grn * 5) / 48; error_grn -= 4 * temp_grn;
- temp_blu = (blu * 5) / 48; error_blu -= 4 * temp_blu;
-
- this_row[ 3] += temp_red; /* this[ 2] += 5/48 */
- this_row[ 4] += temp_grn;
- this_row[ 5] += temp_blu;
-
- next_row[ 3] += temp_red; /* next[ 1] += 5/48 */
- next_row[ 4] += temp_grn;
- next_row[ 5] += temp_blu;
-
- next_row[-3] += temp_red; /* next[-1] += 5/48 */
- next_row[-2] += temp_grn;
- next_row[-1] += temp_blu;
-
- botm_row[ 0] += temp_red; /* botm[ 0] += 5/48 */
- botm_row[ 1] += temp_grn;
- botm_row[ 2] += temp_blu;
-
- temp_red = (red * 3) / 48; error_red -= 4 * temp_red;
- temp_grn = (grn * 3) / 48; error_grn -= 4 * temp_grn;
- temp_blu = (blu * 3) / 48; error_blu -= 4 * temp_blu;
-
- next_row[ 6] += temp_red; /* next[ 2] += 3/48 */
- next_row[ 7] += temp_grn;
- next_row[ 8] += temp_blu;
-
- next_row[-6] += temp_red; /* next[-2] += 3/48 */
- next_row[-5] += temp_grn;
- next_row[-4] += temp_blu;
-
- botm_row[ 3] += temp_red; /* botm[ 1] += 3/48 */
- botm_row[ 4] += temp_grn;
- botm_row[ 5] += temp_blu;
-
- botm_row[-3] += temp_red; /* botm[-1] += 3/48 */
- botm_row[-2] += temp_grn;
- botm_row[-1] += temp_blu;
-
- temp_red = (red * 1) / 48; error_red -= temp_red;
- temp_grn = (grn * 1) / 48; error_grn -= temp_grn;
- temp_blu = (blu * 1) / 48; error_blu -= temp_blu;
-
- botm_row[-6] += temp_red; /* botm[-2] += 1/48 */
- botm_row[-5] += temp_grn;
- botm_row[-4] += temp_blu;
-
- botm_row[ 6] += error_red; /* botm[ 2] += 1/48 */
- botm_row[ 7] += error_grn;
- botm_row[ 8] += error_blu;
-
- next_row += 3; /* adjust next_row pointer */
- botm_row += 3; /* adjust botm_row pointer */
-
- }
- rove += line_length;
- }
- free(buffer);
- return FALSE;
- }
-
-
-